From 59dc466a7f4e6f18bc0c57785ce88b1d4e24ee23 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 5 Mar 2024 15:02:16 -0600 Subject: [PATCH] Trap and do basic reporting on encoding exceptions, both client and server-side --- src/pgwui_upload_core/views/upload.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/pgwui_upload_core/views/upload.py b/src/pgwui_upload_core/views/upload.py index a676f03..acb735b 100644 --- a/src/pgwui_upload_core/views/upload.py +++ b/src/pgwui_upload_core/views/upload.py @@ -42,6 +42,7 @@ from pgwui_core.constants import ( TAB, ) +from pgwui_core import exceptions as core_ex from pgwui_upload_core import exceptions as upload_ex @@ -145,12 +146,32 @@ class BaseTableUploadHandler(TabularFileUploadHandler): self.write_double_key(response) return response + def _execute(self, stmt, tupl): + '''Execute a statement and express encoding errors + ''' + try: + self.cur.execute(stmt, tupl) + except UnicodeEncodeError as err: + raise core_ex.SQLEncodingError( + err, + ("Data cannot be represented in the database" + " connection's client-side character encoding"), + (f'The SQL statement is ({stmt}) and the data supplied' + f' is ({tupl})')) + except psycopg.errors.UntranslatableCharacter as err: + raise core_ex.SQLEncodingError( + err, + ("Data cannot be represented in the" + " character encoding of the database"), + (f'The SQL statement is ({stmt}) and the data supplied' + f' is ({tupl})')) + def resolve_normalized_table(self, qualified_table): '''Return (schema, table) tuple of table name, or raise exception if not resolvable. ''' try: - self.cur.execute( + self._execute( ('SELECT nspname, relname' ' FROM pg_class' ' JOIN pg_namespace' @@ -213,7 +234,7 @@ class BaseTableUploadHandler(TabularFileUploadHandler): # tables.is_insertable_into does not reflect whether # there's an insert trigger on the table. " OR tables.table_type = 'VIEW')") - self.cur.execute(sql, (table, schema)) + self._execute(sql, (table, schema)) return self.cur.fetchone() is not None def quote_columns(self, settings): @@ -298,7 +319,7 @@ class BaseTableUploadHandler(TabularFileUploadHandler): bad_cols = [] for col_name in data.headers.tuples: # Check that colum name exists - self.cur.execute(column_sql, (table, schema, col_name)) + self._execute(column_sql, (table, schema, col_name)) if self.cur.fetchone() is None: bad_cols.append(col_name) else: -- 2.34.1